﻿using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Model.DocumentDB
{
    /// <summary>Represents a DocumentDB database.</summary>
    public class DatabaseViewModel : DocumentClientViewModelBase<AccountViewModel>
    {
        private readonly Database _db;

        /// <summary>Constructor.</summary>
        /// <param name="client">Client API of the account.</param>
        /// <param name="db">Database object.</param>
        /// <param name="parent">Parent of the model.</param>
        internal DatabaseViewModel(DocumentClient client, Database db, AccountViewModel parent)
            : base(client, parent)
        {
            if (db == null)
            {
                throw new ArgumentNullException("db");
            }

            _db = db;
            CollectionFolder = new FolderViewModel<CollectionViewModel, DatabaseViewModel>(
                this,
                "Collections",
                true,
                CollectionViewModel.GetLazyCollection(Client, db.CollectionsLink, this));
            Artefacts = new FolderViewModel[]
            {
                CollectionFolder,
                new FolderViewModel<int,DatabaseViewModel>(this,"Users", false, LoadableCollection<int>.CreateEmpty())
            }.ToList();
        }

        /// <summary>Returns a lazy-loading collection of databases of a given account.</summary>
        /// <param name="client">Client API of the account.</param>
        /// <param name="parent">Parent of the model.</param>
        /// <returns>DB collection.</returns>
        internal static LoadableCollection<DatabaseViewModel> GetLazyDatabases(DocumentClient client, AccountViewModel parent)
        {
            if (client == null)
            {
                throw new ArgumentNullException("client");
            }

            return new LoadableCollection<DatabaseViewModel>(async () =>
            {
                var dbs = await client.ReadDatabaseFeedAsync();
                var models = from db in dbs
                             let model = new DatabaseViewModel(client, db, parent)
                             orderby model.Name
                             select model;

                return models;
            });
        }

        /// <summary>Database name.</summary>
        public string Name
        {
            get { return _db.Id; }
        }

        /// <summary>Database link.</summary>
        public string SelfLink
        {
            get { return _db.SelfLink; }
        }

        /// <summary>Artefacts of a database.</summary>
        public List<FolderViewModel> Artefacts { get; private set; }

        /// <summary>Collections of the account.</summary>
        public FolderViewModel<CollectionViewModel, DatabaseViewModel> CollectionFolder { get; private set; }

        /// <summary>Asynchronously creates a collection under the DB.</summary>
        /// <param name="id">Collection id.</param>
        /// <returns>Created collection.</returns>
        public async Task<CollectionViewModel> CreateCollectionAsync(string id)
        {
            var collection = new DocumentCollection { Id = id };

            collection = await Client.CreateDocumentCollectionAsync(SelfLink, collection);

            var model = new CollectionViewModel(Client, collection, this);

            CollectionFolder.FolderContent.Add(model);

            return model;
        }

        /// <summary>Delete a collection.</summary>
        /// <param name="collection">Collection to delete</param>
        /// <returns>Asynchronous completion.</returns>
        public async Task DeleteCollectionAsync(CollectionViewModel collection)
        {
            await Client.DeleteDocumentCollectionAsync(collection.SelfLink);

            CollectionFolder.FolderContent.Remove(collection);
        }
    }
}